home *** CD-ROM | disk | FTP | other *** search
/ Acorn RISC PD-CD 1 / Acorn RISC PD-CD 1.iso / utilities / _graphics / graphics / _jpeg / c / jdmain < prev    next >
Encoding:
Text File  |  1991-10-28  |  8.1 KB  |  290 lines

  1. /*
  2.  * jdmain.c
  3.  *
  4.  * Copyright (C) 1991, Thomas G. Lane.
  5.  * This file is part of the Independent JPEG Group's software.
  6.  * For conditions of distribution and use, see the accompanying README file.
  7.  *
  8.  * This file contains a trivial test user interface for the JPEG decompressor.
  9.  * It should work on any system with Unix- or MS-DOS-style command lines.
  10.  *
  11.  * Two different command line styles are permitted, depending on the
  12.  * compile-time switch TWO_FILE_COMMANDLINE:
  13.  *      djpeg [options]  inputfile outputfile
  14.  *      djpeg [options]  [inputfile]
  15.  * In the second style, output is always to standard output, which you'd
  16.  * normally redirect to a file or pipe to some other program.  Input is
  17.  * either from a named file or from standard input (typically redirected).
  18.  * The second style is convenient on Unix but is unhelpful on systems that
  19.  * don't support pipes.  Also, you MUST use the first style if your system
  20.  * doesn't do binary I/O to stdin/stdout.
  21.  */
  22.  
  23. #include "jinclude.h"
  24. #ifdef __STDC__
  25. #include <stdlib.h>             /* to declare exit() */
  26. #endif
  27.  
  28. #ifdef THINK_C
  29. #include <console.h>            /* command-line reader for Macintosh */
  30. #endif
  31.  
  32. #ifdef DONT_USE_B_MODE          /* define mode parameters for fopen() */
  33. #define READ_BINARY     "r"
  34. #define WRITE_BINARY    "w"
  35. #else
  36. #define READ_BINARY     "rb"
  37. #define WRITE_BINARY    "wb"
  38. #endif
  39.  
  40.  
  41. /*
  42.  * If your system has getopt(3), you can use your library version by
  43.  * defining HAVE_GETOPT.  By default, we use the PD 'egetopt'.
  44.  */
  45.  
  46. #ifdef HAVE_GETOPT
  47. extern int getopt PP((int argc, char **argv, char *optstring));
  48. extern char * optarg;
  49. extern int optind;
  50. #else
  51. #include "egetopt.c"
  52. #define getopt(argc,argv,opt)   egetopt(argc,argv,opt)
  53. #endif
  54.  
  55.  
  56. typedef enum {                  /* defines known output image formats */
  57.         FMT_PPM,                /* PPM/PGM (PBMPLUS formats) */
  58.         FMT_GIF,                /* GIF format */
  59.         FMT_TIFF                /* TIFF format */
  60. } IMAGE_FORMATS;
  61.  
  62. static IMAGE_FORMATS requested_fmt;
  63.  
  64.  
  65. /*
  66.  * This routine gets control after the input file header has been read.
  67.  * It must determine what output file format is to be written,
  68.  * and make any other decompression parameter changes that are desirable.
  69.  */
  70.  
  71. METHODDEF void
  72. d_ui_method_selection (decompress_info_ptr cinfo)
  73. {
  74.   /* if grayscale or CMYK input, force similar output; */
  75.   /* else leave the output colorspace as set by options. */
  76.   if (cinfo->jpeg_color_space == CS_GRAYSCALE)
  77.     cinfo->out_color_space = CS_GRAYSCALE;
  78.   else if (cinfo->jpeg_color_space == CS_CMYK)
  79.     cinfo->out_color_space = CS_CMYK;
  80.  
  81.   /* select output file format */
  82.   /* Note: jselwxxx routine may make additional parameter changes,
  83.    * such as forcing color quantization if it's a colormapped format.
  84.    */
  85.   switch (requested_fmt) {
  86. #ifdef GIF_SUPPORTED
  87.   case FMT_GIF:
  88.     jselwgif(cinfo);
  89.     break;
  90. #endif
  91. #ifdef PPM_SUPPORTED
  92.   case FMT_PPM:
  93.     jselwppm(cinfo);
  94.     break;
  95. #endif
  96.   default:
  97.     ERREXIT(cinfo->emethods, "Unsupported output file format");
  98.     break;
  99.   }
  100. }
  101.  
  102.  
  103. /*
  104.  * Reload the input buffer after it's been emptied, and return the next byte.
  105.  * See the JGETC macro for calling conditions.
  106.  *
  107.  * This routine would need to be replaced if reading JPEG data from something
  108.  * other than a stdio stream.
  109.  */
  110.  
  111. METHODDEF int
  112. read_jpeg_data (decompress_info_ptr cinfo)
  113. {
  114.   cinfo->bytes_in_buffer = fread(cinfo->input_buffer + MIN_UNGET,
  115.                                  1, JPEG_BUF_SIZE,
  116.                                  cinfo->input_file);
  117.   
  118.   cinfo->next_input_byte = cinfo->input_buffer + MIN_UNGET;
  119.   
  120.   if (cinfo->bytes_in_buffer <= 0)
  121.     ERREXIT(cinfo->emethods, "Unexpected EOF in JPEG file");
  122.  
  123.   return JGETC(cinfo);
  124. }
  125.  
  126.  
  127.  
  128. LOCAL void
  129. usage (char * progname)
  130. /* complain about bad command line */
  131. {
  132.   fprintf(stderr, "usage: %s ", progname);
  133.   fprintf(stderr, "[-b] [-q colors] [-2] [-d] [-g] [-G]");
  134. #ifdef TWO_FILE_COMMANDLINE
  135.   fprintf(stderr, " inputfile outputfile\n");
  136. #else
  137.   fprintf(stderr, " [inputfile]\n");
  138. #endif
  139.   exit(2);
  140. }
  141.  
  142.  
  143. /*
  144.  * The main program.
  145.  */
  146.  
  147. GLOBAL void
  148. main (int argc, char **argv)
  149. {
  150.   struct decompress_info_struct cinfo;
  151.   struct decompress_methods_struct dc_methods;
  152.   struct external_methods_struct e_methods;
  153.   int c;
  154.  
  155.   /* On Mac, fetch a command line. */
  156. #ifdef THINK_C
  157.   argc = ccommand(&argv);
  158. #endif
  159.  
  160.   /* Initialize the system-dependent method pointers. */
  161.   cinfo.methods = &dc_methods;
  162.   cinfo.emethods = &e_methods;
  163.   jselerror(&e_methods);        /* error/trace message routines */
  164.   jselvirtmem(&e_methods);      /* memory allocation routines */
  165.   dc_methods.d_ui_method_selection = d_ui_method_selection;
  166.   dc_methods.read_jpeg_data = read_jpeg_data;
  167.  
  168.   /* Allocate memory for input buffer. */
  169.   cinfo.input_buffer = (char *) (*cinfo.emethods->alloc_small)
  170.                                         ((size_t) (JPEG_BUF_SIZE + MIN_UNGET));
  171.   cinfo.bytes_in_buffer = 0;    /* initialize buffer to empty */
  172.  
  173.   /* Set up default input and output file references. */
  174.   /* (These may be overridden below.) */
  175.   cinfo.input_file = stdin;
  176.   cinfo.output_file = stdout;
  177.  
  178.   /* Set up default parameters. */
  179.   e_methods.trace_level = 0;
  180.   cinfo.output_gamma = 1.0;
  181.   cinfo.quantize_colors = FALSE;
  182.   cinfo.two_pass_quantize = FALSE;
  183.   cinfo.use_dithering = FALSE;
  184.   cinfo.desired_number_of_colors = 256;
  185.   cinfo.do_block_smoothing = FALSE;
  186.   cinfo.do_pixel_smoothing = FALSE;
  187.   cinfo.out_color_space = CS_RGB;
  188.   cinfo.jpeg_color_space = CS_UNKNOWN;
  189.   /* setting any other value in jpeg_color_space overrides heuristics */
  190.   /* in jrdjfif.c ... */
  191.   /* You may wanta change the default output format; here's the place: */
  192. #ifdef PPM_SUPPORTED
  193.   requested_fmt = FMT_PPM;
  194. #else
  195.   requested_fmt = FMT_GIF;
  196. #endif
  197.  
  198.   /* Scan parameters */
  199.   
  200.   while ((c = getopt(argc, argv, "bq:2DdgG")) != EOF)
  201.     switch (c) {
  202.     case 'b':                   /* Enable cross-block smoothing. */
  203.       cinfo.do_block_smoothing = TRUE;
  204.       break;
  205.     case 'q':                   /* Do color quantization. */
  206.       { int val;
  207.         if (optarg == NULL)
  208.           usage(argv[0]);
  209.         if (sscanf(optarg, "%d", &val) != 1)
  210.           usage(argv[0]);
  211.         cinfo.desired_number_of_colors = val;
  212.       }
  213.       cinfo.quantize_colors = TRUE;
  214.       break;
  215.     case '2':                   /* Use two-pass quantization. */
  216.       cinfo.two_pass_quantize = TRUE;
  217.       break;
  218.     case 'D':                   /* Use dithering in color quantization. */
  219.       cinfo.use_dithering = TRUE;
  220.       break;
  221.     case 'd':                   /* Debugging. */
  222.       e_methods.trace_level++;
  223.       break;
  224.     case 'g':                   /* Force grayscale output. */
  225.       cinfo.out_color_space = CS_GRAYSCALE;
  226.       break;
  227.     case 'G':                   /* GIF output format. */
  228.       requested_fmt = FMT_GIF;
  229.       break;
  230.     case '?':
  231.     default:
  232.       usage(argv[0]);
  233.       break;
  234.     }
  235.  
  236.   /* Select the input and output files */
  237.  
  238. #ifdef TWO_FILE_COMMANDLINE
  239.  
  240.   if (optind != argc-2) {
  241.     fprintf(stderr, "%s: must name one input and one output file\n", argv[0]);
  242.     usage(argv[0]);
  243.   }
  244.   if ((cinfo.input_file = fopen(argv[optind], READ_BINARY)) == NULL) {
  245.     fprintf(stderr, "%s: can't open %s\n", argv[0], argv[optind]);
  246.     exit(2);
  247.   }
  248.   if ((cinfo.output_file = fopen(argv[optind+1], WRITE_BINARY)) == NULL) {
  249.     fprintf(stderr, "%s: can't open %s\n", argv[0], argv[optind+1]);
  250.     exit(2);
  251.   }
  252.  
  253. #else /* not TWO_FILE_COMMANDLINE -- use Unix style */
  254.  
  255.   if (optind < argc-1) {
  256.     fprintf(stderr, "%s: only one input file\n", argv[0]);
  257.     usage(argv[0]);
  258.   }
  259.   if (optind < argc) {
  260.     if ((cinfo.input_file = fopen(argv[optind], READ_BINARY)) == NULL) {
  261.       fprintf(stderr, "%s: can't open %s\n", argv[0], argv[optind]);
  262.       exit(2);
  263.     }
  264.   }
  265.  
  266. #endif /* TWO_FILE_COMMANDLINE */
  267.   
  268.   /* Set up to read a JFIF or baseline-JPEG file. */
  269.   /* A smarter UI would inspect the first few bytes of the input file */
  270.   /* to determine its type. */
  271. #ifdef JFIF_SUPPORTED
  272.   jselrjfif(&cinfo);
  273. #else
  274.   You shoulda defined JFIF_SUPPORTED.   /* deliberate syntax error */
  275. #endif
  276.  
  277.   /* Do it to it! */
  278.   jpeg_decompress(&cinfo);
  279.  
  280.   /* Release memory. */
  281.   (*cinfo.emethods->free_small) ((void *) cinfo.input_buffer);
  282. #ifdef MEM_STATS
  283.   if (e_methods.trace_level > 0)
  284.     j_mem_stats();
  285. #endif
  286.  
  287.   /* All done. */
  288.   exit(0);
  289. }
  290.